#ifndef _STREAMER_HPP_20120414
#define _STREAMER_HPP_20120414

#include "base.hpp"
#include "type_trait.hpp"
#include "listbuffer.hpp"

using namespace tools;

namespace buffer
{
	class Streamer
	{
		public :
			enum
			{
				ISTREAMER = 0,
				OSTREAMER = 1,
			};

		public :
			Streamer(uint16_t type, ListBuffer & listbuffer)
				: _type(type),
			      _list_buffer(listbuffer)
			{
			}

		public :
			uint16_t     _type;

			ListBuffer & _list_buffer;

			template <typename _T>
				Streamer & serialize(_T & val, Int2Type<true>)
				{
					if (Streamer::OSTREAMER == _type)
					{
						buffer::bits::get(_list_buffer, val);	
					}
					else
					{
						buffer::bits::put(_list_buffer, val);
					}

					return *this;
				}

			template <typename _T>
				Streamer & serialize(_T & val, Int2Type<false>)
				{
					val.serialize(*this);
					return *this;
				}
		private :
			Streamer(const Streamer &);
			Streamer & operator = (const Streamer &);
	};

	template <typename _T>
		Streamer & operator & (Streamer & streamer, _T & val)
		{
			return streamer.serialize(val, Int2Type<TypeTrait<_T>::base_type>());
		}
};

#endif

